﻿using FlowCanvas;
using LogSystem;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
using Yoozoo.Core.Common;
using Yoozoo.Core.Timeline;
using Yoozoo.Gameplay.City;
using Yoozoo.Gta.Common;
using Yoozoo.HRP.Runtime;

namespace Yoozoo.Gameplay.Liberty
{
    public class PlayingQTETimelineInfo
    {
        public string timeLineName;
        public FlowNode node;
        public string ResultEvent;
    }

    public class TimelineCamera
    {
        public string name;
        public Vector3 position;
        public Vector3 eulerAngles;
        
        // ....
    }

    public enum ETimelinePathType
    {
        City = 1,
        Survivor = 2,
    }
    
    public class TimelineManager
    {
        public static Action<string> OnTimelinePlay;
        public static Action<string> OnTimelineStop;

        public PlayingQTETimelineInfo playingQTETimelineInfo;
        private Dictionary<string, bool> timelineNameMap;
        private Dictionary<string, PlayableDirector> timelineMap;

        private string preTimelineName = "";
        private TimelineConstructor _currentConstructor;

        private Vector3 pos = Vector3.zero;
        public void PlayTimeline(string tname, Action<PlayableDirector> onStop,
            Action<PlayableDirector> onStart = null,
            Action onPreStart = null,
            Action onError = null,
            DirectorWrapMode wrapMode = DirectorWrapMode.None,
        string path = "", string cameraType = "", float planeDistance = 0, Transform parent = null,ETimelinePathType timelinePathType = ETimelinePathType.City)
        {
            if (timelineNameMap == null)
            {
                timelineNameMap = new Dictionary<string, bool>();
            }

            if (timelineNameMap.ContainsKey(tname))
            {
                Debug.LogError(LogModule.Blueprint,"重复播放Timeline：" + tname);
                if (onError != null)
                {
                    onError?.Invoke();
                }
                return;
            }

            if (_currentConstructor && _currentConstructor.gameObject!=null)
            {
                if (_currentConstructor)
                {
                    _currentConstructor.Ban();
                }
            }
            
            timelineNameMap[tname] = true;
            PlayableDirector director = null;
            
            TimelineConstructorMgr.GetInstance("").GetTimelineConstructor(tname, (constructor =>
            {
                var trans = constructor.gameObject.transform;
                trans.localScale = Vector3.one;
                if (parent)
                {
                    trans.parent = parent;
                    trans.localPosition = Vector3.zero;
                    trans.localEulerAngles = Vector3.zero;
                }
                else
                {
                    trans.position = Vector3.zero;
                }
                

                if (constructor.setCube)
                {
                    constructor.setCube.SetMaterial();
                }
                
                if (constructor.audioListener)
                {
                    constructor.audioListener.enabled = true;
                }

                if (constructor.virtualCameras!=null)
                {
                    foreach (var virtualCamera in constructor.virtualCameras)
                    {
                        if (virtualCamera && !virtualCamera.enabled)
                        {
                            virtualCamera.enabled = true;
                        }
                    }
                }
                
                if (constructor.effectSounds!=null)
                {
                    foreach (var e in constructor.effectSounds)
                    {
                        if (e && !e.enabled) {
                            e.enabled = true;
                        }
                    }
                }

                //constructor.gameObject.SetActive(true);
                //Timers.inst.CallLater((o =>
                //{
                    
                if (!timelineNameMap.ContainsKey(tname))
                {
                    // 还没加载出来就被被停止播放了
                    if (onError != null)
                    {
                        onError?.Invoke();
                    }
                    return;
                }
                onPreStart?.Invoke();
                
                if (constructor.tLineCamera)
                {
                    ResidentHandler.Inst.GetFunction("G_CommonDialogHelper.BindTimelineCamera").Action(constructor.tLineCamera);
                    
                    //Timers.inst.CallLater((o =>
                    //{
                        // 延迟一帧开启相机，人物动作那边还是T型 没有刷新
                        if (constructor.tHCamera)
                        {
                           HCameraManager.EnableCamera(constructor.tHCamera);
                        }
                    //}));
                }

                if (constructor.cinemachineBrain)
                {
                    constructor.cinemachineBrain.enabled = true;
                }
                
                var sceneDetector = constructor.GetComponentInChildren<SceneDetectorBase>();
                if (sceneDetector)
                {
                    if (CityManager.Instance)
                        CityManager.Instance.SceneDetector = sceneDetector;

                    // 如果要强刷，在蓝图中使用 RefreshSceneDetector 节点
                }

                director = constructor.playableDirector;

                if (director)
                {
                    director.extrapolationMode = wrapMode;
                    TimelineAsset timelineAsset = (TimelineAsset)director.playableAsset;
                    if (TimelineUtils.FreeRenderScene)
                    {
                        foreach (var playableBinding in timelineAsset.outputs)
                        {
                            if (playableBinding.streamName == "H Timeline Post Process Track")
                            {
                                VolumeQualityListener qualityListener = TimelineUtils.FreeRenderScene
                                    .GetComponentInChildren<VolumeQualityListener>();
                                GameObject volumeObj = qualityListener
                                    .styleSettings[qualityListener.styleSettings.Count - 1].Volume
                                    .gameObject; // 得到最高品质的后效
                                director.SetGenericBinding(playableBinding.sourceObject, volumeObj);
                            }
                        }
                    }
                }

                if (timelineMap == null)
                {
                    timelineMap = new Dictionary<string, PlayableDirector>();
                }

                if (director!=null)
                {
                    timelineMap[tname] = director;
                }

                //Timers.inst.CallLater((o =>
                //{
                    if (onStart!=null)
                    {
                        OnTimelinePlay?.Invoke(tname);
                        onStart?.Invoke(director);
                    }
                //}));
                
                director.paused += (playableDirector =>
                {
                    // 缓存一下Timeline的相机信息
                    CacheTimelineCameraData(constructor);
                });
                director.stopped += (playableDirector =>
                {

                    // 缓存一下Timeline的相机信息
                    CacheTimelineCameraData(constructor);
                    
                    if (onStop != null)
                    {
                        OnTimelineStop?.Invoke(tname);
                        onStop?.Invoke(playableDirector);
                    }

                    // 移除监视器
                    if (CityManager.Instance)
                        CityManager.Instance.SceneDetector = null;
                    
                    ResidentHandler.Inst.GetFunction("G_CommonDialogHelper.UnBindTimelineCamera").Action(0);
                });

                if (!String.IsNullOrEmpty(preTimelineName) && preTimelineName != tname)
                {
                    StopTimeline(preTimelineName);
                }
                preTimelineName = tname;
                _currentConstructor = constructor;
                
                 if (constructor.pausing)
                 {
                     director.timeUpdateMode = DirectorUpdateMode.GameTime;
                     director.Resume();
                 }
                 else
                 {
                    director.Play();
                 }
                }), path, cameraType, planeDistance,timelinePathType); 
            //}));
            
        }
        
        public TimelineCamera TimelineCamera;
        
        private void CacheTimelineCameraData(TimelineConstructor constructor)
        {
            if (constructor)
            {
                Camera tCamera = constructor.tLineCamera;
                if (tCamera == null)
                {
                    tCamera = constructor.GetComponentInChildren<Camera>();
                }

                if (tCamera)
                {
                    // Debug.LogWarning($"CacheTimelineCameraData name:{constructor.tLineName}, position:{tCamera.transform.position}, eulerAngles:{tCamera.transform.eulerAngles}");
                    TimelineCamera = new TimelineCamera()
                    {
                        name = constructor.tLineName,
                        position = tCamera.transform.position,
                        eulerAngles = tCamera.transform.eulerAngles
                    };
                }
                else
                {
                    HCamera hCamera = HCameraManager.GetBaseCamera();
                    // 如果Timeline没有相机，那么拿到当前主摄像机的信息
                    if (hCamera)
                    {
                        // Debug.LogWarning($"CacheTimelineCameraData name:\"\", position:{hCamera.Camera.transform.position}, eulerAngles:{hCamera.Camera.transform.eulerAngles}");
                        TimelineCamera = new TimelineCamera()
                        {
                            name = "",
                            position = hCamera.Camera.transform.position,
                            eulerAngles = hCamera.Camera.transform.eulerAngles
                        };
                    }
                    else
                    {
                        TimelineCamera = null;
                    }
                }
                
            }
            // else
            // {
            //     Debug.LogWarning($"CacheTimelineCameraData constructor = null");
            // }
        }


        public void StopTimeline(string tname)
        {
            // Timers.inst.CallLater((o =>
            // {
            //   // 相机开启延迟一帧，这里对应也要延迟一帧销毁Timeline，否则会穿帮
                if (timelineNameMap!=null && timelineNameMap.ContainsKey(tname))
                {
                    timelineNameMap.Remove(tname);
                }
               TimelineConstructorMgr.GetInstance("").DestroyTimelineConstructor(tname);
               timelineMap?.Remove(tname);
            //}));
        }

        public void StopCurrentTimeline()
        {
            if (!String.IsNullOrEmpty(preTimelineName))
            {
                StopTimeline(preTimelineName);
            }
        }

        public PlayableDirector GetTimelineObject(string name)
        {
            timelineMap.TryGetValue(name, out var pd);
            return pd;
        }
        
        public void JumpToTime(string tname , double toTime)
        {
            if (!timelineNameMap.ContainsKey(tname))
            {
                return;
            }
            PlayableDirector director;
            if (timelineMap.TryGetValue(tname, out director))
            {
                director.time = toTime;
                director.Play();
            }
        }

        public void ResetAll()
        {
            preTimelineName = "";
            timelineMap?.Clear();
            timelineNameMap?.Clear();
            TimelineConstructorMgr.GetInstance("")?.ResetTimelines();
        }

        public void OnDispose()
        {
            if (!String.IsNullOrEmpty(preTimelineName))
            {
                StopTimeline(preTimelineName);
            }
        }

        public void PlayQTETimeline(string timeLineName, FlowNode node)
        {
            if (playingQTETimelineInfo == null)
            {
                playingQTETimelineInfo = new PlayingQTETimelineInfo();
            }
            playingQTETimelineInfo.timeLineName = timeLineName;
            playingQTETimelineInfo.node = node;
        }

        public void UpdateQTETimelineResultName(string eventName)
        {
            playingQTETimelineInfo.ResultEvent = eventName;
        }

        public PlayingQTETimelineInfo GetPlayingQTETimelineInfo()
        {
            return playingQTETimelineInfo;
        }


        private List<PlayableDirector> pausedTimelines = new List<PlayableDirector>();

        private Dictionary<Animator,float> pausedAnimators = new Dictionary<Animator,float>();
        public void Pause()
        {
            pausedTimelines.Clear();
            if (timelineMap != null)
            {
                foreach (var item in timelineMap.Values)
                {
                    if (item != null && item.state == PlayState.Playing)
                    {
                        pausedTimelines.Add(item);
                        item.Pause();
                        var animators = item.gameObject.GetComponentsInChildren<Animator>();
                        for (int i = 0; i < animators.Length; i++)
                        {
                            var animator = animators[i];
                            pausedAnimators[animator] = animator.speed;
                            animator.speed = 0;
                        }
                    }
                }
            }
        }

        public void Resume()
        {
            for (int i = 0; i < pausedTimelines.Count; i++)
            {
                pausedTimelines[i]?.Resume();
            }
            pausedTimelines.Clear();
            foreach (var item in pausedAnimators)
            {
                item.Key.speed = item.Value;
            }
            pausedAnimators.Clear();
        }

        public void CacheCurrentTimelineCamera()
        {
            CacheTimelineCameraData(_currentConstructor);
        }
    }
}
